package com.scs.application.modules.design.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.CacheUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.design.dto.DataViewDTO;
import com.scs.application.modules.design.entity.DataView;
import com.scs.application.modules.design.mapper.DataViewMapper;
import com.scs.application.modules.design.service.DataViewService;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统文件上传表 服务实现类
 * </p>
 */

@Slf4j
@Service
public class TableDataViewServiceImpl extends BaseServiceImpl<DataViewMapper, DataView> implements DataViewService, ApplicationRunner {
    @Override
    public List<DataViewDTO> getDataViewList() {
        List<DataView> dataViews = this.list(Wrappers.<DataView>query().select("view_key,view_name,module_name,description,view_type,columns,creator,gmt_create,modifier,gmt_modified").orderByAsc("view_name"));
        if (dataViews != null && dataViews.size() > 0) {
            List<DataViewDTO> dataViewDTOS = Lists.newArrayListWithCapacity(dataViews.size());
            for(DataView dataView : dataViews) {
                DataViewDTO dataViewDTO = new DataViewDTO();
                dataViewDTO.setViewKey(dataView.getViewKey()).setViewName(dataView.getViewName())
                        .setModuleName(dataView.getModuleName()).setDescription(dataView.getDescription())
                        .setViewType(dataView.getViewType()).setColumns(dataView.getColumns().toJSONString())
                        .setCreator(dataView.getCreator()).setModifier(dataView.getModifier())
                        .setTimeCreated(dataView.getGmtCreate())
                        .setTimeModified(dataView.getGmtModified());
                dataViewDTOS.add(dataViewDTO);
            }

            return  dataViewDTOS;
        }
        return null;
    }

    @Override
    public Boolean deleteView(String viewKey) {
        this.remove(Wrappers.<DataView>query().eq("view_key", viewKey));
        CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, viewKey);
        return true;
    }

    @Override
    public JSONObject saveView(JSONObject dataViewJson) {
        String viewKey = dataViewJson.getString("viewKey");
        String editStatus = dataViewJson.getString("editStatus");
        BusinessException.throwErrorIf(StringUtils.isBlank(viewKey), "视图标志不可以为空");
        DataView dataView = getDataViewFromJSON(dataViewJson, viewKey, editStatus);
        if (StringUtils.isBlank(dataView.getId())) {
            this.save(dataView);
        } else {
            this.updateById(dataView);
        }
        CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey());
        CacheUtils.put(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey(), dataView.getJsonObject().toJSONString());
        dataViewJson.put("id",dataView.getId());
        return dataViewJson;
    }

    /**
     * 从JSON数据库获取DataView
     *
     * @param jsonObject
     * @return
     */
    private DataView getDataViewFromJSON(JSONObject jsonObject, String viewKey, String editStatus) {
        DataView dataView1 = this.getOne(Wrappers.<DataView>query().eq("view_key", viewKey).select("id,view_key").last("limit 1"));
        if ("addNew".equalsIgnoreCase(editStatus) && dataView1 != null) {
            // 新增的化要检查viewKey的唯一性
            throw new BusinessException("viewKey已经存在，请重新命名！");
        }

        DataView dataView = new DataView();
        dataView.setViewKey(viewKey)
                .setViewName(jsonObject.getString("viewName"))
                .setModuleName(jsonObject.getString("moduleName"))
                .setDescription(jsonObject.getString("description"))
                .setViewType(jsonObject.getString("viewType"))
                .setColumns(jsonObject.getJSONArray("columns"))
                .setJsonObject(jsonObject);
        if (dataView1 != null) {
            dataView.setId(dataView1.getId());
        }
        return dataView;
    }

    @Override
    public String listWithSvnLock() {
        return "";
    }

    @Override
    public String getView(String viewKey) {
        DataView dataView = this.getOne(Wrappers.<DataView>query().eq("view_key", viewKey).last("limit 1"));
        if (dataView != null) {
            return dataView.getJsonObject().toJSONString();
        }
        return null;
    }

    @Override
    public List<String> getDataviewViewKeyList() {
        return this.list().stream().map(DataView::getViewKey).collect(Collectors.toList());
    }

    @Override
    public Boolean isSupport(Boolean flagProject) {
        return flagProject;
    }

    @Override
    @Synchronized
    @Transactional(rollbackFor = Exception.class)
    public String syncDataViewsAll() {
        BusinessException.throwError("方法已废弃");
        return null;
    }


    @Override
    public  void cacheDataview(String viewKeyOne) {
        log.info("#########cacheDataview缓存开始#########");
        int num = 1;
        if (StringUtils.isNotBlank(viewKeyOne)) {
            DataView dataView = this.getOne(Wrappers.<DataView>query().eq("view_key",viewKeyOne));
            CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey());
            CacheUtils.put(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey(), dataView.getJsonObject().toJSONString());
        } else {
            List<DataView> dataViewList = this.list(Wrappers.<DataView>query().select("view_key,json_object"));
            num = dataViewList.size();
            for (DataView dataView : dataViewList) {
                try {
                    CacheUtils.remove(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey());
                    CacheUtils.put(CacheUtils.DATAVIEW_CACHE, dataView.getViewKey(), dataView.getJsonObject().toJSONString());
                } catch (Exception ex) {
                    log.error(ex.getMessage());
                }

            }
        }
        log.info("#########cacheDataview缓存结束，更新数据视图长度：{}#########", num);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        this.cacheDataview(null);
    }
}
